#!/usr/bin/env python3
# encoding=utf-8


class IPv6Score:

    DNS_SCORE = 20
    HTTP_GET_SEQUENCE_SCORE = 20
    HTTP_CONTENT_CHECK_SCORE = 5
    IPV6_DNS_CHECK_SCORE = 5
    IPV6_WEBSITE_SUPPORT_CHECK_SECONDARY_SCORE = 15
    IPV6_WEBSITE_SUPPORT_CHECK_TERTIARY_SCORE = 15

    def __init__(self, detail):
        event_detail = parse_ipv6_website_support_check(detail)
        self.detail = event_detail
        self._dns_score = None
        self._http_get_sequence_score = None
        self._http_content_check_score = None
        self._ipv6_dns_check_score = None
        self._ipv6_website_support_check_secondary_score = None
        self._ipv6_website_support_check_tertiary_score = None

    @property
    def total_score(self):
        score = round(
            (
                self.dns_score
                + self.http_get_page_score
                + self.http_get_sequence_score
                + self.ipv6_dns_check_score
                + self.http_content_check_score
                + self.ipv6_website_support_check_secondary_score
                + self.ipv6_website_support_check_tertiary_score
            ),
            2,
        )
        return score

    @property
    def dns_score(self):
        if self._dns_score is None:
            dns = self.detail.get("dns") or {}
            self._dns_score = self.DNS_SCORE if dns.get("address_v6") else 0
        return int(self._dns_score)

    @property
    def http_get_page_score(self):
        return self.http_get_sequence_score

    @property
    def http_get_sequence_score(self):
        if self._http_get_sequence_score is None:
            http_get_sequence = self.detail.get("http_get_sequence") or {}
            success_count = 0
            for res in http_get_sequence.get("ipv6_result", []):
                status_code = res.get('status') or 0
                if status_code not in [0, 405, 501]:
                    success_count += 1
            self._http_get_sequence_score = (
                self.HTTP_GET_SEQUENCE_SCORE if success_count >= 8 else 0
            )
        return self._http_get_sequence_score

    @property
    def http_content_check_score(self):
        if self._http_content_check_score is None:
            http_content_check = self.detail.get("http_content_check") or {}
            similarity = http_content_check.get("similarity") or 0
            self._http_content_check_score = (
                self.HTTP_CONTENT_CHECK_SCORE if similarity >= 0.8 else 0
            )
        return self._http_content_check_score

    @property
    def ipv6_dns_check_score(self):
        if self._ipv6_dns_check_score is None:
            ipv6_dns_check = self.detail.get("ipv6_dns_check") or {}
            is_all_support_ipv6 = ipv6_dns_check.get("is_all_support_ipv6") or False
            self._ipv6_dns_check_score = (
                self.IPV6_DNS_CHECK_SCORE if is_all_support_ipv6 else 0
            )
        return self._ipv6_dns_check_score

    @property
    def ipv6_website_support_check_secondary_score(self):
        if self._ipv6_website_support_check_secondary_score is None:
            ipv6_website_support_check = (
                self.detail.get("ipv6_website_support_check") or {}
            )
            secondary_urls_statistics = (
                ipv6_website_support_check.get("secondary_urls_statistics") or {}
            )
            intra_normal_urls_proportion = (
                float(secondary_urls_statistics["intra_normal_urls_proportion"])
                if secondary_urls_statistics.get("intra_normal_urls_proportion")
                else 0
            )
            self._ipv6_website_support_check_secondary_score = round(
                (
                    intra_normal_urls_proportion
                    * self.IPV6_WEBSITE_SUPPORT_CHECK_SECONDARY_SCORE
                ),
                2,
            )
        return self._ipv6_website_support_check_secondary_score

    @property
    def ipv6_website_support_check_tertiary_score(self):
        if self._ipv6_website_support_check_tertiary_score is None:
            ipv6_website_support_check = (
                self.detail.get("ipv6_website_support_check") or {}
            )
            tertiary_urls_statistics = (
                ipv6_website_support_check.get("tertiary_urls_statistics") or {}
            )
            intra_normal_urls_proportion = (
                float(tertiary_urls_statistics["intra_normal_urls_proportion"])
                if tertiary_urls_statistics.get("intra_normal_urls_proportion")
                else 0
            )
            self._ipv6_website_support_check_tertiary_score = round(
                (
                    intra_normal_urls_proportion
                    * self.IPV6_WEBSITE_SUPPORT_CHECK_TERTIARY_SCORE
                ),
                2,
            )
            if self.ipv6_website_support_check_secondary_score == 0:
                self._ipv6_website_support_check_tertiary_score = 0
        return self._ipv6_website_support_check_tertiary_score


def ipv6_support_check(detail):
    dns = detail.get('dns', {})
    ipv6_dns_check = detail.get('ipv6_dns_check', {})
    ipv6_http_get_sequences = (
        detail.get('http_get_sequence', {}).get('ipv6_result') or []
    )
    ipv6_rate = get_http_get_sequence_rate(ipv6_http_get_sequences)

    if (
        dns.get('address_v6')
        and ipv6_dns_check.get('is_all_support_ipv6')
        and ipv6_rate >= 0.8
    ):
        return True
    return False


def get_http_get_sequence_rate(http_get_sequences):
    success_count = 0
    for http_get_sequence in http_get_sequences:
        status_code = http_get_sequence.get('status') or 0
        if status_code not in [0, 405, 501]:
            success_count += 1
    return round((success_count / 10), 2)


def parse_ipv6_website_support_check(event_detail):
    ipv6_website_support_check = event_detail.get("ipv6_website_support_check") or {}
    ipv6_address = event_detail.get("dns", {}).get("address_v6") or []
    http_get_full_time = event_detail.get("http_get_full_time") or {}
    keys = ["secondary_urls_statistics", "tertiary_urls_statistics"]
    for key in keys:
        urls_statistics = ipv6_website_support_check.get(key) or {}
        intra_urls_count = urls_statistics.get('intra_urls_count')
        if intra_urls_count == 0:
            if ipv6_address and http_get_full_time.get('status_v6', 0) == 200:
                urls_statistics['intra_normal_urls_proportion'] = 1
            else:
                urls_statistics['intra_normal_urls_proportion'] = 0
    if ipv6_website_support_check.get("secondary_urls_statistics", {}).get("intra_normal_urls_proportion", 0) == 0:
        ipv6_website_support_check.setdefault("tertiary_urls_statistics", {})
        ipv6_website_support_check["tertiary_urls_statistics"].update({"intra_normal_urls_proportion": 0})
    return event_detail


def parse_ipv6_event(detail):
    if not isinstance(detail, dict):
        return detail
    score_obj = IPv6Score(detail)
    # DNS记录
    dns = detail.get('dns') or {}
    dns['ipv6_score'] = score_obj.dns_score
    # 域名授权体系
    ipv6_dns_check = detail.get('ipv6_dns_check') or {}
    ipv6_dns_check['ipv6_score'] = score_obj.ipv6_dns_check_score
    ipv6_dns_check['is_all_support_ipv4'] = True if dns.get('address') else False
    # 网站首页IPv6访问成功率
    http_get_sequence = detail.get('http_get_sequence') or {}
    ipv6_http_get_sequences = http_get_sequence.get('ipv6_result') or []
    http_get_sequence['ipv6_success_proportion'] = get_http_get_sequence_rate(
        ipv6_http_get_sequences
    )
    http_get_sequence['ipv6_score'] = score_obj.http_get_sequence_score
    # 首页可达
    ipv4_http_get_sequences = http_get_sequence.get('ipv4_result') or []
    http_get_page = {
        'ipv6_score': score_obj.http_get_page_score,
        'is_ipv6_support': bool(score_obj.http_get_page_score),
        'is_ipv4_support': bool(
            get_http_get_sequence_rate(ipv4_http_get_sequences) >= 0.8
        ),
    }
    detail['http_get_page'] = http_get_page
    # 网站二级链接IPv6支持率
    ipv6_website_support_check = detail.get('ipv6_website_support_check') or {}
    secondary_urls_statistics = (
        ipv6_website_support_check.get("secondary_urls_statistics") or {}
    )
    secondary_urls_statistics[
        'ipv6_score'
    ] = score_obj.ipv6_website_support_check_secondary_score
    # 网站三级链接IPv6支持率
    tertiary_urls_statistics = (
        ipv6_website_support_check.get("tertiary_urls_statistics") or {}
    )
    tertiary_urls_statistics[
        'ipv6_score'
    ] = score_obj.ipv6_website_support_check_tertiary_score
    # 网站首页内容IPv6和IPv4的一致性
    http_content_check = detail.get('http_content_check') or {}
    http_content_check['ipv6_score'] = score_obj.http_content_check_score
    total_score = score_obj.total_score
    return detail, total_score
